package org.vectrics.common.db;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.vectrics.SystemException;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.hibernate.HibernateUtil;
import org.vectrics.provider.CoreServiceLocator;

public class SurrogateKeyRunnable implements Runnable {
	private transient Logger log = Logger.getLogger(SurrogateKeyRunnable.class);
	private String surrogateKeyCode = null;
	private Long id = null;

	public SurrogateKeyRunnable(String surrogateKeyCode) {
		super();
		this.surrogateKeyCode = surrogateKeyCode;
	}

	public Long getId() {
		return(id);
	}

	
	
	public synchronized void run() {
        HibernateUtil hibernate = (HibernateUtil)CoreServiceLocator.findServiceBean("hibernate.util");
        Session session = hibernate.createNewSession();
		Transaction trx = session.beginTransaction();
		runWithHibernateObjects(session);
//		this.runWithJdbcCalls(session);
		session.flush();
    	trx.commit();
    	session.close();
	}
	
	private void runWithHibernateObjects(Session session) {
		log.debug("Surrogate key runnable.run()");
		SurrogateKey surrogateKey = (SurrogateKey)session.load(SurrogateKey.class, this.surrogateKeyCode);
		id = surrogateKey.getId();
		
		if (log.isDebugEnabled())
			log.debug("Surrogate key, code = " + this.surrogateKeyCode + " Current id = " + id);
		
		if (id.compareTo(surrogateKey.getStartId()) < 0) {
			if (log.isDebugEnabled())
				log.debug("Surrogate key less than surrogate's start id, setting to start id - code = " + this.surrogateKeyCode);
			id = surrogateKey.getStartId();
		}
		
		surrogateKey.setId(new Long(id.longValue() + 1));
		if (surrogateKey.getId().longValue() <= id.longValue())
			throw new SystemException("Logic error, saving incremented id, not greater than previous");
		session.update(surrogateKey);

		/*		
		surrogateKey = (SurrogateKey)session.load(SurrogateKey.class, this.surrogateKeyCode);
		if (surrogateKey.getId().longValue() != id.longValue())
			throw new SystemException("Exception getting surrogate key, readback failed");
			*/
	}

	
	private void runWithJdbcCalls(Session session) {
		// Get id and starting id from sequence
		
		SurrogateKeyJdbcTarget target = new SurrogateKeyJdbcTarget(this.surrogateKeyCode);
		JdbcExecute.execute(session, target);
		
		/*
		String getSequenceFieldsSql = 
			"select srgt_ky_id, srgt_ky_strt_id from srgt_key where srgt_ky_cd= :code";
		Session session = HibernateSessionStore.getSession();
		Connection connection = session.connection();
		List sequenceFields = session.createSQLQuery(getSequenceFieldsSql)
			.addScalar("srgt_ky_id", new LongType())
			.addScalar("srgt_ky_strt_id", new LongType())
		    .setString("code", code)
		    .list();
		if (sequenceFields.size() > 1)
			throw new SystemException("More than one record returned for surrogate key");
		if (sequenceFields.size() < 1)
			throw new SystemException("No records returned for surrogate key");
		Object object = sequenceFields.iterator().next();
		log.debug("Object type: " + object.getClass().getName());
		log.info("Object string: " + object.toString());
		*/
		id = target.getNextId();
		Long startId = target.getStartId();
		if (log.isDebugEnabled())
			log.debug("New Surrogate key = " + id);
		
		if (id == null) 
			throw new SystemException("Next id is null");
		if (id.longValue() < startId.longValue()) {
			id = startId;
		}
		Long nextId = new Long(id.longValue() + 1);
		
		// Update id in sequence
		String updateSql = "update srgt_key set srgt_ky_id = " + nextId.toString() 
			+ " where srgt_ky_cd = '" + this.surrogateKeyCode + "'";
		JdbcUpdate.execute(session, updateSql);
	}

	
}
